#include <string.h>

#ifndef WIN32
#include <pthread.h>
#endif

#include "common.h"
#include "Util.h"


using namespace Scenic::Renderer;


bool Scenic::Renderer::convert(char *src, int srcPitch, Format srcFormat, char *dest, int dstPitch, Format dstFormat,
	int width, int height)
{
	int xx, yy;
	
	if(dstFormat == srcFormat)
	{
		int size = Device::getFormatSize(srcFormat);
		
		for(yy = 0; yy < height; yy++)
		{
			memcpy(dest, src, width * size);
			dest += dstPitch;
			src += srcPitch;
		}
	}
	else if(dstFormat == FMT_A8R8G8B8 && srcFormat == FMT_R8G8B8)
	{
		for(yy = 0; yy < height; yy++)
		{
			for(xx = 0; xx < width; xx++)
			{
				dest[xx * 4] = src[xx * 3];
				dest[xx * 4 + 1] = src[xx * 3 + 1];
				dest[xx * 4 + 2] = src[xx * 3 + 2];
				dest[xx * 4 + 3] = (char)255;
			}
			dest += dstPitch;
			src += srcPitch;
		}
	}
	else if(dstFormat == FMT_A8R8G8B8 && srcFormat == FMT_L8)
	{
		for(yy = 0; yy < height; yy++)
		{
			for(xx = 0; xx < width; xx++)
			{
				dest[xx * 4] = src[xx];
				dest[xx * 4 + 1] = src[xx];
				dest[xx * 4 + 2] = src[xx];
				dest[xx * 4 + 3] = (char)255;
			}
			dest += dstPitch;
			src += srcPitch;
		}
	}
	else if(dstFormat == FMT_A8R8G8B8 && srcFormat == FMT_A8)
	{
		for(yy = 0; yy < height; yy++)
		{
			for(xx = 0; xx < width; xx++)
			{
				dest[xx * 4] = 0;
				dest[xx * 4 + 1] = 0;
				dest[xx * 4 + 2] = 0;
				dest[xx * 4 + 3] = src[xx];
			}
			dest += dstPitch;
			src += srcPitch;
		}
	}
	else if(dstFormat == FMT_A8R8G8B8 && srcFormat == FMT_AL8)
	{
		for(yy = 0; yy < height; yy++)
		{
			for(xx = 0; xx < width; xx++)
			{
				dest[xx * 4] = src[xx];
				dest[xx * 4 + 1] = src[xx];
				dest[xx * 4 + 2] = src[xx];
				dest[xx * 4 + 3] = src[xx];
			}
			dest += dstPitch;
			src += srcPitch;
		}
	}
	else
		return false;
	return true;
}

//
// CriticalSection
//

CriticalSection::CriticalSection()
{
#ifdef WIN32
	InitializeCriticalSection(&criticalSection);
#else
	pthread_mutexattr_t a;
	
	pthread_mutexattr_init(&a);
	pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&mutex, &a);
	pthread_mutexattr_destroy(&a);
#endif
}

CriticalSection::~CriticalSection()
{
#ifdef WIN32
	DeleteCriticalSection(&criticalSection);
#else
#endif
}

void CriticalSection::enterCriticalSection()
{
#ifdef WIN32
	EnterCriticalSection(&criticalSection);
#else
	pthread_mutex_lock(&mutex);
#endif
}

void CriticalSection::leaveCriticalSection()
{
#ifdef WIN32
	LeaveCriticalSection(&criticalSection);
#else
	pthread_mutex_unlock(&mutex);
#endif
}


